using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace ServiceStack
{
	public static class IPAddressExtensions
	{
		public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask)
		{
			byte[] addressBytes = address.GetAddressBytes();
			byte[] addressBytes2 = subnetMask.GetAddressBytes();
			if (addressBytes.Length != addressBytes2.Length)
			{
				throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
			}
			byte[] array = new byte[addressBytes.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (addressBytes[i] | (addressBytes2[i] ^ 255));
			}
			return new IPAddress(array);
		}
		public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
		{
			byte[] arg_0E_0 = address.GetAddressBytes();
			byte[] addressBytes = subnetMask.GetAddressBytes();
			return new IPAddress(IPAddressExtensions.GetNetworkAddressBytes(arg_0E_0, addressBytes));
		}
		public static byte[] GetNetworkAddressBytes(byte[] ipAdressBytes, byte[] subnetMaskBytes)
		{
			if (ipAdressBytes.Length != subnetMaskBytes.Length)
			{
				throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
			}
			byte[] array = new byte[ipAdressBytes.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (ipAdressBytes[i] & subnetMaskBytes[i]);
			}
			return array;
		}
		public static bool IsInSameIpv6Subnet(this IPAddress address2, IPAddress address)
		{
			if (address2.AddressFamily != AddressFamily.InterNetworkV6 || address.AddressFamily != AddressFamily.InterNetworkV6)
			{
				throw new ArgumentException("Both IPAddress must be IPV6 addresses");
			}
			byte[] arg_2D_0 = address.GetAddressBytes();
			byte[] addressBytes = address2.GetAddressBytes();
			return arg_2D_0.IsInSameIpv6Subnet(addressBytes);
		}
		public static bool IsInSameIpv6Subnet(this byte[] address1Bytes, byte[] address2Bytes)
		{
			if (address1Bytes.Length != address2Bytes.Length)
			{
				throw new ArgumentException("Lengths of IP addresses do not match.");
			}
			for (int i = 0; i < 8; i++)
			{
				if (address1Bytes[i] != address2Bytes[i])
				{
					return false;
				}
			}
			return true;
		}
		public static bool IsInSameIpv4Subnet(this IPAddress address2, IPAddress address, IPAddress subnetMask)
		{
			if (address2.AddressFamily != AddressFamily.InterNetwork || address.AddressFamily != AddressFamily.InterNetwork)
			{
				throw new ArgumentException("Both IPAddress must be IPV4 addresses");
			}
			object arg_2D_0 = address.GetNetworkAddress(subnetMask);
			IPAddress networkAddress = address2.GetNetworkAddress(subnetMask);
			return arg_2D_0.Equals(networkAddress);
		}
		public static bool IsInSameIpv4Subnet(this byte[] address1Bytes, byte[] address2Bytes, byte[] subnetMaskBytes)
		{
			if (address1Bytes.Length != address2Bytes.Length)
			{
				throw new ArgumentException("Lengths of IP addresses do not match.");
			}
			byte[] arg_23_0 = IPAddressExtensions.GetNetworkAddressBytes(address1Bytes, subnetMaskBytes);
			byte[] networkAddressBytes = IPAddressExtensions.GetNetworkAddressBytes(address2Bytes, subnetMaskBytes);
			return arg_23_0.AreEqual(networkAddressBytes);
		}
		public static Dictionary<IPAddress, IPAddress> GetAllNetworkInterfaceIpv4Addresses()
		{
			Dictionary<IPAddress, IPAddress> dictionary = new Dictionary<IPAddress, IPAddress>();
			try
			{
				NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
				for (int i = 0; i < allNetworkInterfaces.Length; i++)
				{
					foreach (UnicastIPAddressInformation current in allNetworkInterfaces[i].GetIPProperties().UnicastAddresses)
					{
						if (current.Address.AddressFamily == AddressFamily.InterNetwork && current.IPv4Mask != null)
						{
							dictionary[current.Address] = current.IPv4Mask;
						}
					}
				}
			}
			catch
			{
			}
			return dictionary;
		}
		public static List<IPAddress> GetAllNetworkInterfaceIpv6Addresses()
		{
			List<IPAddress> list = new List<IPAddress>();
			try
			{
				NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
				for (int i = 0; i < allNetworkInterfaces.Length; i++)
				{
					foreach (UnicastIPAddressInformation current in allNetworkInterfaces[i].GetIPProperties().UnicastAddresses)
					{
						if (current.Address.AddressFamily == AddressFamily.InterNetworkV6)
						{
							list.Add(current.Address);
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}
	}
}
